home *** CD-ROM | disk | FTP | other *** search
/ The Mac Mega CD - Killer Software / The Mac Mega CD - Killer Software (May 1996).dmg / Shareware City / Sound / MacMikMod 2.10+src / source / mikmod.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-04  |  5.1 KB  |  229 lines  |  [TEXT/CWIE]

  1. /*
  2.  
  3. Name:
  4. MIKMOD.C
  5.  
  6. Description:
  7. Modplaying example of mikmod.
  8.  
  9. MSDOS:    BC(y)    Watcom(y)    DJGPP(y)
  10. Win95:    BC(y*)
  11. Os2:    y
  12. Linux:    n
  13.  
  14. * console mode only
  15. (y) - yes
  16. (n) - no (not possible or not useful)
  17. (?) - may be possible, but not tested
  18.  
  19. */
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <SIOUX.h>
  25.  
  26. #include "mikmod.h"
  27.  
  28. void tickhandler(void)
  29. {
  30.     MP_HandleTick();    /* play 1 tick of the module */
  31.     MD_SetBPM(mp_bpm);
  32. }
  33.  
  34. static short isPressed(unsigned short k)
  35. {
  36.     unsigned char km[16];
  37.  
  38.     GetKeys((unsigned long*) km);
  39.     return ((km[k>>3] >> (k & 7)) & 1);
  40. }
  41.  
  42. static Boolean CmdPeriod(void)
  43. {
  44.     if (isPressed(0x37) && isPressed(0x0C))
  45.     {
  46.         FlushEvents(keyDownMask + mDownMask, 0);
  47.         return TRUE;
  48.     }
  49.     return FALSE;
  50. }
  51.  
  52. static void pstrcat(StringPtr dst, StringPtr src)
  53. /*
  54.  * pstrcat - add string 'src' to end of string 'dst'
  55.  */
  56. {
  57.     /* copy string in */
  58.     BlockMove(src + 1, dst + *dst + 1, *src);
  59.     /* adjust length byte */
  60.     *dst += *src;
  61. }
  62.  
  63. static void pstrinsert(StringPtr dst, StringPtr src)
  64. /*
  65.  * pstrinsert - insert string 'src' at beginning of string 'dst'
  66.  */
  67. {
  68.     /* make room for new string */
  69.     BlockMove(dst + 1, dst + *src + 1, *dst);
  70.     /* copy new string in */
  71.     BlockMove(src + 1, dst + 1, *src);
  72.     /* adjust length byte */
  73.     *dst += *src;
  74. }
  75.  
  76. static OSErr PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName)
  77. {
  78.     DirInfo    block;
  79.     Str255    directoryName;
  80.     OSErr    err;
  81.  
  82.     fullPathName[0] = '\0';
  83.  
  84.     block.ioDrParID = dirID;
  85.     block.ioNamePtr = directoryName;
  86.     do {
  87.         block.ioVRefNum = vRefNum;
  88.         block.ioFDirIndex = -1;
  89.         block.ioDrDirID = block.ioDrParID;
  90.         err = PBGetCatInfo((CInfoPBPtr) &block, FALSE);
  91.         if (err != noErr)
  92.             return err;
  93.         pstrcat(directoryName, (StringPtr)"\p:");
  94.         pstrinsert(fullPathName, directoryName);
  95.     } while (block.ioDrDirID != 2);
  96.     return noErr;
  97. }
  98.  
  99. static OSErr PathNameFromWD(long vRefNum, StringPtr pathName)
  100. /*
  101.  * PathNameFromWD:
  102.  * Given an HFS working directory, this routine returns the full pathname that
  103.  * corresponds to it. It does this by calling PBGetWDInfo to get the VRefNum and
  104.  * DirID of the real directory. It then calls PathNameFromDirID, and returns its
  105.  * result.
  106.  */
  107. {
  108.     WDPBRec    myBlock;
  109.     OSErr    err;
  110.     
  111.     if (vRefNum == -1)
  112.         PathNameFromDirID(2, -1, pathName);
  113.     else {
  114.         myBlock.ioNamePtr = nil;
  115.         myBlock.ioVRefNum = vRefNum;
  116.         myBlock.ioWDIndex = 0;
  117.         myBlock.ioWDProcID = 0;
  118.         err = PBGetWDInfo(&myBlock, FALSE);
  119.         if (err != noErr)
  120.             return err;
  121.         PathNameFromDirID(myBlock.ioWDDirID, myBlock.ioWDVRefNum, pathName);
  122.     }
  123.     return noErr;
  124. }
  125. void main(void)
  126. {
  127.     EventRecord    event;
  128.     UNIMOD *mf;
  129.     int cmderr=0;                   /* error in commandline flag */
  130.     int morehelp=0;                 /* set if user wants more help */
  131.     int quit;
  132.     int t;
  133.     Str255    fName;
  134.     
  135.     puts(mikbanner);
  136.  
  137.     /*
  138.         Initialize soundcard parameters.. you _have_ to do this
  139.         before calling MD_Init(), and it's illegal to change them
  140.         after you've called MD_Init()
  141.     */
  142.  
  143.     md_mixfreq      =44100;                     /* standard mixing freq */
  144.     md_dmabufsize   =10000;                     /* standard dma buf size */
  145.     md_mode         =DMODE_16BITS|DMODE_STEREO | DMODE_INTERP; /* standard mixing mode */
  146.     md_device       =0;                                                     /* standard device: autodetect */
  147.     
  148.     /*
  149.         Register the loaders we want to use..
  150.     */
  151.  
  152.     ML_RegisterLoader(&load_m15);    /* if you use m15load, register it as first! */
  153.     ML_RegisterLoader(&load_mod);
  154.     ML_RegisterLoader(&load_mtm);
  155.     ML_RegisterLoader(&load_s3m);
  156.     ML_RegisterLoader(&load_stm);
  157.     ML_RegisterLoader(&load_ult);
  158.     ML_RegisterLoader(&load_uni);
  159.     ML_RegisterLoader(&load_xm);
  160.  
  161.     /*
  162.         Register the drivers we want to use:
  163.     */
  164.  
  165.     MD_RegisterDriver(&drv_mac);
  166.     MD_RegisterPlayer(tickhandler);
  167.  
  168.     /* Parse option switches using standard getopt function: */
  169.     /*  initialize soundcard */
  170.  
  171.     if(!MD_Init()){
  172.         printf("Driver error: %s.\n",myerr);
  173.         return;
  174.     }
  175.  
  176.     printf("Playing %d bit %s %s sound at %.1f kHz\n\n",
  177.             (md_mode&DMODE_16BITS) ? 16:8,
  178.             (md_mode&DMODE_INTERP) ? "interpolated":"normal",
  179.             (md_mode&DMODE_STEREO) ? "stereo":"mono",
  180.             md_mixfreq / 1000.0);
  181.     
  182.     // [DEMOS] -> Standard open file
  183.     {
  184.         SFReply                reply;
  185.         SFTypeList             typeList = { '????' };
  186.         Point                where = { -1, -1 };
  187.         
  188.         SFGetFile(where, "\pOpen MOD file:", NULL, -1, typeList, NULL, &reply);
  189.         if (!reply.good) {
  190.             return;
  191.         }
  192.         PathNameFromWD(reply.vRefNum, fName);
  193.         pstrcat(fName, reply.fName);
  194.         PtoCstr(fName);
  195.     }
  196.     mf=ML_LoadFN((char*) fName);
  197.     if (mf == NULL)
  198.     {
  199.         printf("Couldn't load mod-file \"%s\"\n\n", fName);
  200.         return;
  201.     }
  202.     /*    initialize modplayer to play this module */
  203.  
  204.     MP_Init(mf);
  205.     printf( "Songname : %s\nMOD-Type : %s\n", mf->songname, mf->modtype);
  206.     /*
  207.         set the number of voices to use.. you
  208.         could add extra channels here (e.g. md_numchn=mf->numchn+4; )
  209.         to use for your own soundeffects:
  210.     */
  211.  
  212.     printf("\nCmd-Period to quit.\n");
  213.     
  214.     md_numchn=mf->numchn;
  215.  
  216.     /*  start playing the module: */
  217.  
  218.     MD_PlayStart();
  219.  
  220.     // [DEMOS] -> Do anything here, synthesise in real-time @ snd interrupt
  221.     while(!MP_Ready()) 
  222.         if (WaitNextEvent(everyEvent, &event, -1, NULL)) 
  223.             SIOUXHandleOneEvent(&event);
  224.     
  225.     MD_PlayStop();          /* stop playing */
  226.     ML_Free(mf);            /* and free the module */
  227.  
  228.     MD_Exit();
  229. }